package com.yao.sys.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yao.common.enums.SysErrorEnum;
import com.yao.common.exception.BusinessException;
import com.yao.common.resp.DTree;
import com.yao.sys.entity.dto.MenuDto;
import com.yao.sys.mapper.MenuMapper;
import com.yao.sys.mapper.sql.MenuWrapper;
import com.yao.sys.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单表 接口实现
 *
 * @author autoCode
 * @version 1.0.0-SNAPSHOT
 * @date 2020-04-09
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, MenuDto> implements MenuService {

    @Autowired
    private MenuMapper mapper;

    @Override
    public void add(MenuDto dto) {
        // 根据名称查询菜单
        MenuDto menu = this.getOne(MenuWrapper.byName(dto.getName()));

        // 不能存在同名菜单
        if (null != menu) {
            throw new BusinessException(SysErrorEnum.ERROR.getErrCode(), "已经存在该[{}]名字的菜单", dto.getName());
        }

        // 设置sort
        if (null == dto.getSort()) {
            dto.setSort(this.getMaxSort(dto.getParentId()));
        }

        if (!this.save(dto)) {
            throw new BusinessException("新增菜单失败.");
        }

    }

    @Override
    @Transactional(isolation = Isolation.REPEATABLE_READ, rollbackFor = BusinessException.class)
    public void modifyById(MenuDto dto) {
        if (null == dto.getId()) {
            throw new BusinessException("更新的id不存在." + dto);
        }

        if (!this.updateById(dto)) {
            throw new BusinessException("更新菜单失败.");
        }
    }

    @Override
    public List<MenuDto> listRoot() {
        return this.list(MenuWrapper.byParentId(0));
    }


    @Override
    public IPage<MenuDto> page(IPage<MenuDto> page, MenuDto dto) {

        Wrapper<MenuDto> query = MenuWrapper.withPage(dto);

        return this.page(page, query);
    }

    /**
     * 功能描述 : 获取当前menu中最大排序
     * 
     * @param
     * @author yaoyuming
     * @date 2020/4/15
     * @return {@link Integer}
     */
    private Integer getMaxSort(Integer parentId) {
        Integer maxSort = 0;
        LambdaQueryWrapper<MenuDto> query = Wrappers.lambdaQuery();
        query.eq(MenuDto::getParentId, parentId).select(MenuDto::getSort);

        List<MenuDto> list = this.list(query);

        if (CollUtil.isNotEmpty(list)) {
            maxSort = list.stream().mapToInt(MenuDto::getSort).max().orElse(0) + 1;
        }

        return maxSort;
    }

    @Override
    @Cacheable(value="menu", key="methodName")
    public List<DTree> tree() {

        List<MenuDto> root = this.listRoot();

        return root.stream().map(menu -> {
            List<DTree> collect = this.list(MenuWrapper.byParentId(menu.getId())).stream().map(MenuDto::of).collect(Collectors.toList());

            DTree tree = MenuDto.of(menu);
            tree.setChildren(collect);
            return tree;
        }).collect(Collectors.toList());
    }

}